var avalon = require('expose?avalon!avalon');

require("expose?jQuery!jquery-1x");
require("bootstrap-2.3.2/js/bootstrap-tab");


require('stylesheets/style.scss');
var defaultImage = require("stylesheets/images/DefaultImg.png");

var _ = require("expose?_!underscore"),
    moment = require("expose?moment!moment");


moment.locale("zh-cn");
// moment().utcOffset(-8);

avalon.config({
    debug: true
})

var htmlTemplate = require("text!./components/flow.timeline.html");
var sample = require("./api/sample.json");


var fixedJavaDate = function(d){
        if(!d) return moment().clone();
        if(moment.isMoment(d)) return d;
        var td = _.extend(d); //@TODO immutable
        delete td.day
        if(td.year<1900) td.year += 1900;
        return moment(td).clone();
    },
    setParameters = function(paramsData){
        var url = "";
         _.each(_.pairs(paramsData),function(a){
            url += "&"+a[0] + "=" + a[1];
        })

        return url.substr(1);
    },
    getParameters = function(url){
        var params = url.split("&"), i,val,paramsData ={};
            for(i = 0; i< params.length;i++){
                val = params[i].split("=");
                paramsData[val[0]] = escape(val[1]);
            }
        return paramsData;
    };

avalon.component('ms-flow-timeline', {
    template: htmlTemplate,
    defaults: {

        $id: "flow-timeline",
        title: 'flow-timeline',
        defaultImage:defaultImage,
        menu:{
            addmenu:{
                name:"添加节目",
                func: function(){}
            },

            currentmenu:{
                name:"当前节目",
                func:function(){}
            },
            importmenu:{
                name:"导入",
                func:function(){}
            },
            listmenu:{
                name:"节目列表",
                func:function(){}
            },
            downloadAppClient:{
              name:"APP客户端下载",
              href:"",
              func:function(){}
            },
            downloadClient:{
                name:"客户端下载",
                href:"",
                func:function(){}
            }
        },
        getCalendar:function(){

        },
        url: "",
        week:[],
        showTable:false,
        thisWeekData:[],
        plainData: [],
        params:{

        },
        pickupday:"",
        cachedData:[],
        currentday: moment(),
        paramsData:{},
        selectedRang:{},
        selectControll:{},

        dayArrAppendIndex:{},
        lazyloadNum:20,
        lazyloadNumAppend :10,
        lazyloadData:{
            // index: lazyloadNum
        },
        emptyArr:[],
        remoteTime: {},
        debug: true,
        lang: {
            loading:"加载中....",
            allterminalGroup:"全部分组",
            preView:"预览",
            pullGetMore:"点击或下拉加载更多..",
            all:"显示全部",
            video: "视频",
            live:"直播",
            notice: "公告",
            groupName:"分组",
            edit_menu:"编辑",
            delete_menu:"删除",
            no_results: "暂无数据"
        },



        $skipArray:["paramsData","toggleWeeks","week","currentday","menu","cachedData","selectedRang","plainData","emptyArr","dayArrAppendIndex"],
        getAWeekDays : function(monday){
            var days = [];
            var startDay = monday.clone().subtract(1,'d');

            _(7).times(function(n){
                var s = startDay.add(1,'d');
                days.push(moment(s).clone());
            })
            return days;
        },


        toggleWeeks: function(dir){
            // console.log(dir,this.currentday);

            if(_.isString(dir)){
                if("preWeek" == dir){
                    var preMonday = this.currentday.clone().subtract( this.currentday.day() +7,'d');
                    this.renderAWeeks(this.getAWeekDays(preMonday));
                    this.currentday = preMonday.clone().add(this.currentday.day(),'d')

                }else if("nextWeek" == dir){


                    var leftDay = this.currentday.day() == 0 ? 0 : 7 % this.currentday.day();
                    var nextMonday = this.currentday.clone().add( (leftDay),'d')
                    this.renderAWeeks(this.getAWeekDays(nextMonday));
                    this.currentday = nextMonday.clone().add(this.currentday.day(),'d')
                }
            }else{
                var pickupMonday = moment(this.pickupday).clone();
                pickupMonday.subtract(pickupMonday.day(),'d');
                this.currentday = moment(this.pickupday).clone();
                this.renderAWeeks(this.getAWeekDays(pickupMonday ));


            }

            this.pickupday = this.currentday.format("YYYY-MM-DD");

            this.currentIndex = this.currentday.day();

        },
        toggleTab:function(index){
            var that = this, i= index;
           this.currentday = this.week[index];
           this.currentIndex = index;
           that.toggleTabAfter(i);
            // $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")").on("scroll",function(e){






        },
         editItemApply:function(e,item, method){
            this[method].apply(this,[item,this.refreshTable]);
        },

        previewApply:function(href,event){
            this['preViewItem'].apply(this,[href,event]);
        },

        refreshTable:function(){
            this.dayArrAppendIndex = {}
            this.renderAWeeks(this.getAWeekDays(this.currentday.clone().subtract(this.currentday.day(),'d') ))
        },

        toggleSelect:function(el,type){

            if(el.target.value == "all"){
                this.selectControll[type] = ""
            }else{
                this.selectControll[type] = "."+el.target.value+"-type-item";
            }
            var selector = ""
            for(var k in this.selectControll){
                selector += this.selectControll[k];

            }
            if(selector != ""){
                var $selectorItems =  $(".active .timeline-panel-content .select-type-item").hide()
                    .parent().find(selector);

                    if($selectorItems.length > 0 )
                    $(".flow-timeline-navigator ul li:eq("+ this.currentIndex +")").find("span.num").html( $selectorItems.length).show();

                    $selectorItems.show();
            }else{

                if(this.plainData[this.currentIndex].thisDayEvents.totalEvent > 0){
                     $(".flow-timeline-navigator ul li:eq("+ this.currentIndex +")").find("span.num").html( this.plainData[this.currentIndex].thisDayEvents.totalEvent).show();
                }

                $(".active .timeline-panel-content .select-type-item").show()
            }

        },

        selectTypeGroup:function(el,type,dEvents){
            var that = this;
            if(dEvents.readAll) return that.toggleSelect(el,type);
            $(".loadingtip").show(function(){

                // console.time("while time")
                while(!dEvents.readAll){
                    that.lazyloadAppend(that.lazyloadNumAppend,function(){

                    });
                }
                 // console.timeEnd("while time")
                $(".loadingtip").hide(function(){
                    that.toggleSelect(el,type)
                })
            })



        },

        clickOrpullGetMore:function(dEvents,index){
            var that = this , i = index ;

            that.lazyloadAppend(that.lazyloadNumAppend,function(){


                var $wrapper = $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")"),
                scrollTop = $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")").children(".timeline-panel-content").height() - $wrapper.height();
                $(".flow-timeline-wrapper  .active.timeline-panel").animate({scrollTop: scrollTop - 20},'slow');

            });
        },

        renderAWeeks: function(week){


            if(_.isString(this.paramsData)){
                this.paramsData = getParameters(this.paramsData);
            }
            this.week = week;

            // console.log("week",week)

            this.paramsData.days = _.map(week, function (k) {
                // console.log(k);
                return k.format("YYYY-MM-DD");
            });
            // console.log("paramsData week",this.paramsData.days)

            var that = this;

            _.map(week,function(k){
                that.lazyloadData[k.day()] = that.lazyloadNum;
            })

            if(this.debug){

                return that.handleJSON.apply(that,[sample]);


             }else{
                that.params.centerDay = that.paramsData.days[4];

                return avalon.vmodels['root'].getCalendar(
                        setParameters(that.params), function(res){
                            that.remoteTime =  fixedJavaDate(JSON.parse(res.key))
                            that.handleJSON(res.list);


                             _.map(that.plainData, function(d,i){
                                if( d.thisDayEvents.totalEvent > 0){

                                    $(".flow-timeline-navigator ul li:eq("+ i +")").find("span.num").html( d.thisDayEvents.totalEvent).show();
                                }else{
                                    $(".flow-timeline-navigator ul li:eq("+ i +")").find("span.num").hide();
                                }
                            })



                        }
                    )

             }




        },

        handleJSON: function(json){
               console.time("json initialize");
                var that = this;
                    _.map(json,function(j){

                        j.moment = fixedJavaDate(j.startTime);
                    })

                    var date_json = _.groupBy(json,function(j){
                        return j.moment.format('YYYY-MM-DD');
                    })



                    // console.log(date_json)
                    var date_array = [];
                    _.each(date_json, function(v,k){
                        var time_group_json = _.groupBy(v, function(j){
                            return j.moment.format('HH')
                        })



                        var time_array = [] ,programTypeGroup ={}, terminalGroup = {}, idGroup=[];
                         _.each(time_group_json, function(val,key){


                            var val2 = _.map(val,function(l){
                                var type="", info={};
                                    if(l.programType ==1 || l.programType == 4 ){
                                        type = "notice";
                                        info = {
                                            Title:l.afficheTitle,
                                            PreView:l.afficheUri
                                            // noticeTypeName:l.noticeTypeName,
                                            // noticeBeginDate:fixedJavaDate(l.noticeBeginDate),
                                            // noticeBeginDateFormat:fixedJavaDate(l.noticeBeginDate).format("HH:MM:SS"),
                                            // noticeEndDate:fixedJavaDate(l.noticeEndDate),
                                            // noticeEndDateFormat:fixedJavaDate(l.noticeEndDate).format("HH:MM:SS")
                                        }


                                    }else if(l.programType ==2 || l.programType ==5){
                                        type = "live";
                                        // console.log(l);
                                        info = {
                                            Title:l.recordEquipmentName,
                                            PreView:l.recordEquipmentNameUri
                                            // liveStatus:l.liveStatus,
                                            // liveStartTime:fixedJavaDate(l.liveStartTime),
                                            // liveStartTimeFormat:fixedJavaDate(l.liveStartTime).format("HH:MM:SS"),
                                            // liveEndTime:fixedJavaDate(l.liveEndTime),
                                            // liveEndTimeFormat:fixedJavaDate(l.liveEndTime).format("HH:MM:SS"),
                                            // liveRecordEquipmentName:l.liveRecordEquipmentName,
                                            // liveTimeTip:l.liveTimeTip,
                                            // liveGradeName:l.liveGradeName

                                        }

                                    }else if(l.programType ==3){
                                        type = "video";
                                        info = {
                                            videoIsWeike:l.videoIsWeike,
                                            videoSpeaker: l.videoSpeaker,
                                            PreView:l.videoUri,
                                            Period:l.videoPeriod ? moment(l.videoPeriod,"S"):moment(0,"S"),
                                            PeriodFormat:l.videoPeriod ? moment(l.videoPeriod,"S").format("HH:MM:SS"):moment(0,"S").format("HH:MM:SS")
                                        }



                                    }else{
                                        type="unknow"
                                    }
                                    if(type!="unknow"){
                                        info = avalon.mix({
                                            Title:l[type+"Title"],
                                            Cover:l[type+"Cover"],
                                            CoverHash:l[type+"CoverHash"],
                                            CoverUri:l[type+"CoverUri"],
                                            Id:l[type+"Id"],
                                            CoverHash:l[type+"CoverHash"]

                                        },info)
                                    }

                                    if(programTypeGroup[type] == undefined){

                                        programTypeGroup[type] ={
                                            gid:type,
                                            name:that.lang[type],
                                            collections:[]
                                        }

                                    }

                                    programTypeGroup[type].collections.push(l.id);

                                    var listTerminalGroupClass = [];

                                    if(l.listTerminalGroup.length){
                                        _.map(l.listTerminalGroup, function(item){
                                            var groupType = "g"+item.id;

                                            listTerminalGroupClass.push("g"+item.id+"-type-item");
                                            if(terminalGroup[groupType] == undefined) {
                                                terminalGroup[groupType] = {
                                                    gid:groupType,
                                                    name: item.name,
                                                    collections:[]
                                                };

                                            }
                                            terminalGroup[groupType].collections.push(l.id);
                                        })
                                    }

                                idGroup.push(l.id);
                                // console.log(l.title);

                                var title = "";


                                if(that.usingInfoTitle){
                                   title = info && info.Title == "" ? l.title: info.Title;
                                }else{
                                    title = l.title;
                                }

                                var startTime = fixedJavaDate(l.startTime)
                                var endTime = fixedJavaDate(l.endTime)

                                var isBetween = that.remoteTime.isBetween(startTime,endTime,"second")

                               return  {
                                    programType:type,
                                    title: title,
                                    id:l.id,
                                    listTerminalGroup:l.listTerminalGroup,
                                    listTerminalGroupClass:listTerminalGroupClass,
                                    // listTerminalGroup:[
                                    //     {
                                    //         id:33
                                    //         name:"北区中学"
                                    //         sortNumber:2
                                    //     }
                                    // ]
                                    // moment:moment(l.startTime)
                                    startTime:startTime,
                                    endTime: endTime,
                                    remoteTime: that.remoteTime,
                                    isBetween: isBetween,
                                    info:info,
                                    show:true,
                                    description:l.description
                                }
                            })

                            // val2 =  _.sortBy(val2, function(v){
                            //     return v.startTime.format('mm')
                            // })

                            val2.reverse();

                            time_array.push( {
                                time:key+":00",
                                show:true,
                                thisTimeEvents:{
                                    totalEvent: val.length,
                                    collections: val2
                                }
                            })
                        })
                        var m = moment(k);
                        var thisDayEvents ={
                                totalEvent: v.length,
                                collections: time_array,
                                idGroup:idGroup,
                                terminalGroup :terminalGroup,
                                programTypeGroup:programTypeGroup
                            };
                        var result = {
                            guid: m.format('x'),
                            EventDate: k,
                            date : m.date(),
                            day: m.day(),
                            moment:m.clone(),
                            thisDayEvents: thisDayEvents
                        }
                        result.thisDayEvents.collections = _.sortBy(result.thisDayEvents.collections,"time")

                        date_array.push( result)

                    })
                console.timeEnd("json initialize");
                json = date_array;

                 // Moment#date is for the date of the month, and Moment#day is for the day of the week.

                 // if(!this.cachedData.length){
                    // this.cachedData = _.map(this.week, function(d){
                        // console.log(json)
               console.time("tempWeek initialize");
                var tempWeek =_.compact(this.week), tempWeekData = {};
                this.thisWeekData = [];


                _.map(json, function(s){
                    var index = _.findIndex(tempWeek, function(d){
                        return moment(s.EventDate).isSame(d,'day');
                    })
                    if(index !== -1){
                        tempWeekData[index] = s;
                    }

                })
                // add blank data to week
                var results = _.map(this.week, function(d,i){


                    if(tempWeekData[i]){

                        return tempWeekData[i]


                    }else{

                        var plain  = {
                             "guid": d.format('x'),
                            "day": d.format('dddd'),
                            "moment": d.clone(),
                            "date": d.date(),
                            "thisDayEvents": {
                                "totalEvent": null
                                ,"collections": []
                            }
                        }



                        return plain;
                    }
                })



                console.timeEnd("tempWeek initialize");
                this.plainData = results.concat([]);


                this.showTable =true; // can't get $(".flow-timeline-wrapper  .active.timeline-panel")
                this.lazyload(this.lazyloadNum,this.registerEvent);



                $(".flow-timeline-wrapper .timeline-panel ").height($(window).height() - 400);

                jQuery('.dateuipick').datepicker();

        },

        registerEvent:function(){
            var that = this,i;



            // i = _.findIndex(that.week,function(d){

            //     return d.isSame(that.currentday,'day');
            // });

             i = that.currentIndex;
             that.toggleTabAfter(i);

        },


        toggleTabAfter:function(index){
            var that = this, i = index;

            $(".flow-timeline-navigator li:eq("+ index +") a").tab("show");


             // console.log($(".flow-timeline-wrapper  .active.timeline-panel"))
                $(".flow-timeline-wrapper  .active.timeline-panel").on("scroll",function(e){

                     if(!that.thisWeekData[i].readAll){
                var $wrapper = $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")"),
                    $content = $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")").children(".timeline-panel-content");


                    var tempScrollTop = $(e.currentTarget).scrollTop();

                    if( tempScrollTop >= $content.height() - $wrapper.height()){
                        // $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")").off("scroll");
                        //$(".flow-timeline-wrapper .active.timeline-panel").off("scroll");

                             that.lazyloadAppend(that.lazyloadNumAppend,function(){
                            // console.log("do nothing")

                                  var scrollTop = $(".flow-timeline-wrapper .timeline-panel:eq(" + i + ")").children(".timeline-panel-content").height() - $wrapper.height();
                                $(e.currentTarget).animate({scrollTop: scrollTop - 20},'fast');
                            });






                    }
                   }
                });


        },

        lazyloadAppend:function(num,cb){

               // console.time("lazyloadAppend initialize");
            var that = this, currentIndex,d;

            // i = _.findIndex(that.week,function(d){

            //     return d.isSame(that.currentday,'day');
            // });

            currentIndex = that.currentIndex;


            d = that.thisWeekData[currentIndex];



            var dayArrAppend = that.plainData[currentIndex].thisDayEvents.collections;
            var dayArr = d.thisDayEvents.collections;


           // console.log("readAll",dayArrAppend.length,
           //  dayArr.length
           //  ,dayArrAppend[dayArrAppend.length - 1].thisTimeEvents.collections.length
           //  ,dayArr[dayArr.length - 1].thisTimeEvents.collections.length )


           // console.log("dayArrAppend, ",dayArrAppend.length,dayArr.length,dayArrAppend[dayArrAppend.length - 1].thisTimeEvents.collections.length , dayArr[dayArr.length - 1].thisTimeEvents.collections.length)
           if(dayArrAppend.length  == dayArr.length   && dayArrAppend[dayArrAppend.length - 1]
              &&  dayArrAppend[dayArrAppend.length - 1].thisTimeEvents.collections.length == dayArr[dayArr.length - 1].thisTimeEvents.collections.length){
                d.readAll = true;
                // console.log("readAll")
                 cb.apply(this);
                 return;
           }
            // console.time("dayArrAppend initialize");
            // each time

            // console.log(" dayArrAppend.length", dayArrAppend.length)



            for( var i = that.dayArrAppendIndex[currentIndex] || 0 ; i < dayArrAppend.length ;i++){


                (function(){
                    var timeArrAppend = dayArrAppend[i].thisTimeEvents.collections;
                    var timeArr = dayArr[i].thisTimeEvents.collections;




                        // console.log(" timeArrAppend.length", timeArrAppend.length, i, num  )

                        //console.time("timeArrAppend initialize");

                        var sliceLength = timeArrAppend.length - timeArr.length;
                        var begin = timeArr.length  ;


                        if(num <= sliceLength ){
                            sliceLength = num;
                            num = -1;
                        }else{
                            num -= sliceLength;
                        }
                        // console.log("num",num)

                        // console.log("sliceLength ",sliceLength, begin,timeArrAppend.length, timeArr.length,timeArrAppend.slice(begin,begin + sliceLength))

                        timeArr.pushArray(timeArrAppend.slice(begin,begin + sliceLength))


                        //console.log("slice after ",sliceLength, begin,timeArrAppend.length, timeArr.length)

                        // each event


                        // for(var t= timeArr.length == 0 ? 0 : timeArr.length ; t < timeArrAppend.length ; ++t){
                        //     // when timeArr.length == timeArrAppend.length
                        //       console.time("push initialize");
                        //    timeArr.push(timeArrAppend[t]);
                        //         console.timeEnd("push initialize");
                        //     num-=1;
                        //     // end loop
                        //     if(num<0){
                        //         break;
                        //     }
                        // }
                        //  console.timeEnd("timeArrAppend initialize");
                  })()

                // end loop
                if(num<0){
                    break;
                }


                // if short
                if(i == dayArr.length -1  &&  i != dayArrAppend.length -1 ) {
                    if( dayArr.length < dayArrAppend.length ){
                        var plain = avalon.mix(true,{},dayArrAppend[i+1]);
                        plain.thisTimeEvents.collections = []
                        dayArr.pushArray( [ plain ]);

                    }

                }

            }

            that.dayArrAppendIndex[currentIndex] = i

             // console.timeEnd("dayArrAppend initialize");
             //  console.timeEnd("lazyloadAppend initialize");
            if(cb){
                cb.apply(this);
            }

        },


        lazyload:function(num,cb){
             var that = this;
             // console.log(that.plainData)
             this.thisWeekData.clear();

             this.thisWeekData = _.map(this.week, function(d,i){

                    var getIndex = [0,num];
                    var copyone = avalon.mix(true,{"dindex":i},that.plainData[i])

                    var dayArr = copyone.thisDayEvents.collections;


                   var  count = getIndex[1] - getIndex[0] - 1, Ti=0,t=0;


                    for(Ti=0; Ti<dayArr.length ;Ti++){

                        var timeArr = dayArr[Ti].thisTimeEvents.collections;

                        //console.log("timeArr",i,num, timeArr.length)
                        for(t=0;t<timeArr.length ;t++){

                            count-=1;
                            if(count < 0){
                                timeArr.splice(t+1,timeArr.length - t-1 );
                                break;
                            }
                        }

                        if(count < 0){

                            dayArr.splice(Ti+1, dayArr.length -Ti-1);
                            break;
                        }


                    }

                    // console.log(Ti,dayArr.length,t,dayArr[dayArr.length -1],copyone , dayArr[dayArr.length -1]?  dayArr[dayArr.length -1].thisTimeEvents.collections.length :"undefined")
                    if(Ti == dayArr.length  && dayArr[dayArr.length -1] && t == dayArr[dayArr.length -1].thisTimeEvents.collections.length ){
                        copyone.readAll = true;
                    }else if(dayArr.length == 0){
                        copyone.readAll = true;
                    }else{
                          copyone.readAll = false;
                    }
                    copyone.loaded = true;

                   return copyone;
                })

            cb.apply(this);

        },



        onInit:function(){

            var that = this;
            this.selectCalendar = this.currentday;
            this.currentIndex = this.currentday.day();

            this.week = this.getAWeekDays(this.currentday.clone().subtract(this.currentday.day(),'d') );

        },
        onReady: function(){

            this.renderAWeeks(this.week);




        },
        onViewChange:function(){
        }

    },
    soleSlot: 'content'
})





module.exports = avalon //注意这里必须返回avalon,用于webpack output配置
